package com.yzc.rabbit;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yzc.constants.MqConstants;
import com.yzc.mapper.OrderStatusLogMapper;
import com.yzc.mapper.TicketMainOrderMapper;
import com.yzc.model.entity.ticket_order.OrderMain;
import com.yzc.model.entity.ticket_order.OrderStatusLog;
import com.yzc.util.RabbitMQUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderConsumerService {

    private final InventoryService inventoryService;
    private final TicketMainOrderMapper orderMainMapper;
    private final ConcurrentHashMap<Long, Integer> delayIndexMap = new ConcurrentHashMap<>();
    private final RabbitMQUtil rabbitMQUtil;
    private final OrderStatusLogMapper logMapper;

    /**
     * 处理未支付订单延迟消息
     *
     * @param orderId 订单ID
     */
    @RabbitListener(queues = MqConstants.ORDER_UNPAID_QUEUE)
    public void handleUnpaidOrder(Long orderId) {
        log.info(" [x] 收到未付款的订单消息，订单ID为: {}", orderId);

        // 1. 查询订单状态
        OrderMain order = orderMainMapper.selectById(orderId);
        log.error(" [x] 查询订单状态，订单ID: {}", orderId);
        if (order == null) {
            log.error("订单不存在，订单ID: {}", orderId);
            return;
        }

        // 2. 检查订单是否已经支付成功
        if (OrderStatus.status_PAID.getCode() == order.getOrderStatus()) {
            log.info("订单已支付成功，无需回滚库存，订单ID: {}", orderId);
            return;
        }

        // 3. 检查订单状态是否为未支付
        if (OrderStatus.status_UNPAID.getCode() != order.getOrderStatus()) {
            log.info("订单状态已更新，无需回滚库存，订单ID: {}", orderId);
            return;
        }

        // 4. 幂等性检查：检查库存是否已经回滚
        if (inventoryService.isInventoryRolledBack(orderId)) {
            log.info("库存已回滚，无需重复操作，订单ID: {}", orderId);
            return;
        }


        // 5. 回滚库存
        inventoryService.rollbackInventory(orderId);
        log.info(" [x] 回滚订单ID的库存: {}", orderId);



        // 6. 更新主订单状态和失败原因
        order.setOrderStatus(OrderStatus.status_CANCELED.getCode()); // 更新为已取消状态
        order.setCancelReason("订单未支付，库存已回滚"); // 记录失败原因
        orderMainMapper.updateById(order);
        log.info(" [x] 更新主订单状态为已取消，订单ID: {}", orderId);

        // 7. 记录操作日志
        OrderStatusLog orderStatusLog = new OrderStatusLog();
        orderStatusLog.setOrderId(orderId);
        orderStatusLog.setStatus(OrderStatus.status_CANCELED.getCode());
        orderStatusLog.setOperator("system"); // 操作人，可以根据业务需求调整
        orderStatusLog.setRemark("订单未支付，库存已回滚");
        orderStatusLog.setCreateTime(new Date());
        logMapper.insert(orderStatusLog);
        log.info(" [x] 记录操作日志，订单ID: {}", orderId);

        // 8. 判断是否需要继续发送下一个延迟消息
        if (isNextDelayNeeded(orderId)) { // 修改为 isNextDelayNeeded
            int nextDelay = getNextDelay(orderId); // 获取下一个延迟时间
            if (nextDelay > 0) { // 如果存在下一个延迟时间
                rabbitMQUtil.sendStaggeredDelayedMessages(
                        MqConstants.DELAY_EXCHANGE_NAME,
                        "order.unpaid",
                        orderId,
                        new int[]{nextDelay} // 发送下一个延迟消息
                );
                log.info(" [x] 发送下一个延迟消息，订单ID: {}, 延迟: {} ms", orderId, nextDelay);
            }
        }
    }

    // 检查库存是否已经回滚,订单的状态是否被设置成了待支付状态
    private boolean isNextDelayNeeded(Long orderId) {
        OrderMain order = orderMainMapper.selectOne(
                new LambdaQueryWrapper<OrderMain>()
                        .eq(OrderMain::getOrderId, orderId)
        );
        return order != null && OrderStatus.status_UNPAID.getCode() == order.getOrderStatus();
    }

    // 获取下一个延迟时间
    private int getNextDelay(Long orderId) {
        int[] delays = rabbitMQUtil.generateDelays();
        int currentIndex = delayIndexMap.getOrDefault(orderId, 0);
        if (currentIndex < delays.length - 1) {
            delayIndexMap.put(orderId, currentIndex + 1);
            return delays[currentIndex + 1];
        }
        return 0; // 无下一个延迟时间
    }

}